/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.abstractvoid.gui;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Map;
import java.util.TreeMap;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import pl.abstractvoid.datamodel.parameters.ParameterSet;
import pl.abstractvoid.datamodel.parameters.ParameterTable;

/**
 * Responsible form displaying input/output data of a distribution.
 * It displays JTable in JScrollPane in JPanel. It is nested in the tabs of 
 * DataInput panel class. Uses custom table models. It also allows for 
 * deletion and creationof table rows with F1,F2 and Delete (for selected rows).
 * Dropdown menu, which allows for displaying AddRemoveRowsQuery, can be used.
 * @author Ivo Zieliński
 */
public final class TablePanel extends JPanel {

    private final MainFrame mediator;
    private ParameterSet parameterSet;

    public TablePanel(MainFrame mediator) {
        this.mediator = mediator;
        this.parameterSet = mediator.getCurrentDistribution().getParameters();
        initComponents();
        setVisible(true);
    }

    public void updateParameters(ParameterSet parameters) {
        this.parameterSet = parameters;
        removeAll();
        initComponents();
        updateUI();
    }
    
    /**
     * Reloads parameters to show the change of the current language.
     */
    public void reloadParameters() {
        removeAll();
        initComponents();
        updateUI();
    }

    /**
     * Initializes the layout and child components
     */
    public void initComponents() {
        GridBagLayout layout = new GridBagLayout();
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.weightx = 1.0;
        gbc.weighty = 0.1;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.fill = GridBagConstraints.BOTH;
        setLayout(layout);
        if (parameterSet.getSingleParameters() != null) {
            JTable tabela = new JTable(new EditableSingleParameterTableModel(parameterSet.getSingleParameters()));
            tabela.getTableHeader().setReorderingAllowed(false);
            JScrollPane primaryScrollPane = new JScrollPane(tabela);
            primaryScrollPane.setVerticalScrollBarPolicy(
                    JScrollPane.VERTICAL_SCROLLBAR_NEVER);
            add(primaryScrollPane, gbc);
        }
        gbc.weighty = 0.5;
        TreeMap<String, ParameterTable> parameterTables = parameterSet.getParameterTables();
        if (parameterTables != null && !parameterTables.isEmpty()) {
            for (Map.Entry pairs : parameterTables.entrySet()) {
                gbc.gridy++;
                ParameterTable parameterTable = (ParameterTable) pairs.getValue();
                //Use custom table model
                final JTable tabela = new JTable(new ParameterTableModel(parameterTable));
                tabela.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
                tabela.addMouseListener(new PopuMenuMouseAdapter());
                //Handle shortucuts
                tabela.addKeyListener(new KeyAdapter() {
                    @Override
                    public void keyPressed(KeyEvent e) {
                        super.keyPressed(e);
                        int code = e.getKeyCode();
                        if (code == KeyEvent.VK_DELETE) {
                            ParameterTableModel tableModel = (ParameterTableModel) tabela.getModel();
                            int ile = tabela.getSelectedRowCount();
                            if (ile != 0 && ile < tabela.getRowCount()) {
                                tableModel.removeRows(tabela.getSelectedRows());
                                tabela.clearSelection();
                                if (tabela.isEditing()) {
                                    tabela.getCellEditor().stopCellEditing();
                                }
                            }
                            tabela.updateUI();
                        }
                        if (code == KeyEvent.VK_F2) {
                            tabela.clearSelection();
                            if (tabela.isEditing()) {
                                tabela.getCellEditor().stopCellEditing();
                            }
                            ParameterTableModel tableModel = (ParameterTableModel) tabela.getModel();
                            tableModel.addRows(1, false);
                            tabela.clearSelection();
                            tabela.updateUI();
                        }
                        if (code == KeyEvent.VK_F1) {
                            tabela.clearSelection();
                            if (tabela.isEditing()) {
                                tabela.getCellEditor().stopCellEditing();
                            }
                            ParameterTableModel tableModel = (ParameterTableModel) tabela.getModel();
                            if (tableModel.getRowCount() > 1) {
                                tableModel.removeRows(1, false);
                                tabela.clearSelection();
                                tabela.updateUI();
                            }
                        }
                    }
                });
                tabela.getTableHeader().setReorderingAllowed(false);
                JScrollPane sp = new JScrollPane(tabela);
                sp.setVerticalScrollBarPolicy(
                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

                add(sp, gbc);
            }
        }
    }

    /**
     * Responsible for displaying dropdown menu
     */
    class PopuMenuMouseAdapter extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.isPopupTrigger()) {
                doPop(e);
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (e.isPopupTrigger()) {
                doPop(e);
            }
        }

        private void doPop(MouseEvent e) {
            InputTablePopupMenu menu = new InputTablePopupMenu(e.getComponent());
            menu.show(e.getComponent(), e.getX(), e.getY());
        }
    }
}
